package com.easytouch.core;

import android.content.Context;
import android.content.SharedPreferences;

import com.easytouch.core.model.GoodsModel;
import com.easytouch.core.utils.Log;
import com.easytouch.core.utils.SDCardTools;
import com.easytouch.core.utils.Tools;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import android_serialport_api.SerialPort;

/**
 * Created by gulin on 2016/7/20.
 */
public class Configure {
    public final static int LOAD_DATA_SUCCESS = 0;
    public final static int ERROR_NO_SDCARD = 1;
    public final static int ERROR_EMPTY_DATA = 2;
    public final static int DATA_ERROR = 3;

    public final static String CONFIG_COMMPORT = "commport";
    public final static String CONFIG_BAUDRATE = "baudrate";
    public final static String CONFIG_MONITOR_OPEN = "monitor";
    public final static String CONFIG_SERVER_IP = "serverIp";
    public final static String CONFIG_SERVER_PORT = "serverPort";
    public final static String CONFIG_PICK_IP = "pickIp";
    public final static String CONFIG_PICK_PORT = "pickPort";
    public final static String CONFIG_VERSION = "version";
    public final static String CONFIG_DEBUG = "debug";
    public final static String CONFIG_PROTECT_TIME = "protectTime";
    public final static String CONFIG_REBOOT_TIME = "rebootTime";

    public final static String CONFIG_PAY_URL = "payUrl"; //三码合一URL
    public final static String CONFIG_PAY_ID = "payId"; //三码合一商户号
    public final static String CONFIG_ALIPAY = "alipay"; //是否开启支付宝支付 0关闭 1API1.0 2API2.0
    public final static int ALIPAY_VERSION_1 = 1;
    public final static int ALIPAY_VERSION_2 = 2;
    public final static String CONFIG_ALIPAY_DISCOUNT = "alipayDiscount"; //支付宝折扣
    public final static String CONFIG_ALIPAY_PARTNER = "alipayPartner"; //支付宝商户号或APPID
    public final static String CONFIG_ALIPAY_NOTIFY_URL = "alipayNotifyUrl"; //支付宝通知URL
    public final static String CONFIG_ALIPAY_KEY = "alipayKey"; //支付宝密钥
    public final static String CONFIG_WECHAT = "wechat"; //是否开启微信支付 0关闭 1微信3.0模式1 2微信3.0模式2
    public final static int WECHAT_MODE_1 = 1;
    public final static int WECHAT_MODE_2 = 2;
    public final static String CONFIG_WECHAT_DISCOUNT = "wechatDiscount"; //微信支付折扣
    public final static String CONFIG_WECHAT_ID = "wechatId"; //微信支付ID
    public final static String CONFIG_WECHAT_KEY = "wechatKey"; //微信支付商户密钥
    public final static String CONFIG_WECHAT_MAC_ID = "wechatMacId"; //微信支付商户ID
    public final static String CONFIG_WECHAT_SUBMAC_ID = "wechatSubMacId"; //微信支付子商户ID
    public final static String CONFIG_WECHAT_NOTIFY_URL = "wechatNotifyUrl"; //微信支付通知URL
    public final static String CONFIG_PAY_IP = "payIp";
    public final static String CONFIG_PAY_PORT = "payPort";
    public final static String CONFIG_CASH = "cash"; //现金支付 0不开启 其他表示开启
    public final static String CONFIG_CARD = "card"; //刷卡支付 0不开启 其他表示开启
    public final static String CONFIG_MOBILE = "mobile"; //手机支付 0不开启 其他表示开启
    public final static String CONFIG_FACE = "face"; //人脸支付 0不开启 其他表示开启

    public final static String DIRECTORY_CONFIG = "config";
    public final static String FILE_CONFIG = "config.ini";
    public final static String FILE_GAME = "game.ini";
    public final static String FILE_GOODS = "goods.xml";
    public final static String FILE_MAIN = "main.ini";
    public final static String FILE_NBPOS = "nbpos.ini";

    public final static String MAIN_DISPLAY_RATE = "displayRate";
    public final static String MAIN_IMAGE_TIME = "imageTime";
    public final static String MAIN_IMAGE_NAMES = "imageNames";
    public final static String MAIN_VIDEO_NAMES = "imageVideos";
    public final static String MAIN_RECOMMEND = "recommend";

    public final static String GAME_ENABLE = "gameEnable";
    public final static String GAME_PACKAGE = "gamePackage";
    public final static String GAME_ACTIVITY = "gameActivity";
    public final static String GAME_GIFT = "gameGift";
    public final static String GAME_CODE = "gameCode";

    public final static String NBPOS_STATE = "nbpos";
    public final static String NBPOS_DISCOUNT = "nbposDiscount";
    public final static String NBPOS_IP = "nbposIp";
    public final static String NBPOS_PORT = "nbposPort";
    public final static String NBPOS_TERM_INFO = "nbposTermInfo";
    public final static String NBPOS_SSL_SN = "nbposSslSn";
    public final static String NBPOS_MCHT_ID = "nbposMchtId";
    public final static String NBPOS_TERM_ID = "nbposTermId";
    public final static String NBPOS_AUTH_SN = "nbposAuthSn";
    public final static String NBPOS_BAUD_RATE = "nbposBaudRate";
    public final static String NBPOS_COMM_PORT = "nbposCommPort";
    public final static String NBPOS_OPER_ID = "nbposOperId";
    public final static String NBPOS_POS_ID = "nbposPosId";


    private static final String AVM_DATA = "avm";
    private static final String AVM_NO = "avm_no";
    private static HashMap<String, String> mConfigMap = new HashMap<String, String>();
    public static boolean isMonitorOpen = false;
    public static boolean isDebug = true;
    public static boolean isGameEnable = false;
    public static int alipayState = 0;
    public static int wechatState = 0;
    public static boolean isCash = true;
    public static boolean isCard = false;
    public static boolean isMobile = true;
    public static boolean isFace = false;
    public static ArrayList<GoodsModel> goodsList = new ArrayList<GoodsModel>(); // XML中所有的商品信息
    private static SharedPreferences mSharedPreferences;
    public static int width = 1280; //屏幕宽度
    public static int height = 720; //屏幕高度
    private static Log mLogger = new Log("configure.txt");
    private static String mMacNo = "00000000"; //售货机编号

    private static HashMap<Integer, Integer> mColumnNumMap = new HashMap<Integer, Integer>(); //货道数量
    /**
     * 主控版本号
     */
    private static String mAvmVersion;
    /**
     * 机器类型
     */
    private static String mMacType;

    /**
     * 饮料机数量
     */
    private static String mDrinkNum;

    /**
     * 食品机数量
     */
    private static String mFoodsNum;

    /**
     * 泡面柜数量
     */
    private static String mNoodleNum;

    /**
     * 饮料机货道数量
     */
    private static String mDrinkColumnNum;

    /**
     * 食品机货道数量
     */
    private static String mFoodsColumnNum;

    /**
     * 泡面柜货道数量
     */
    private static String mNoodleColumnNum;

    private static String mUUID = "000000000000000000000000"; //主控的24位唯一ID号

    public static final String MONITOR_VERSION = "14"; //后台监控报文版本号

    public static Context context = null;
    public static String path = "/sdcard/Android/data/com.easytouch.vm";
    public static String version = "1.0.01";

//    /**
//     * 隐藏system bar
//     */
//    public static void hideSystemBar()
//    {
//        SystemTools.hideSystemBar();
//    }

    /**
     * 读取基本配置
     * @return 读取结果
     */
    public static int loadConfig() {
        if(context == null || path == null || version == null)
        {
            return DATA_ERROR;
        }
        width = context.getResources().getDisplayMetrics().widthPixels;
//        height = context.getResources().getDisplayMetrics().heightPixels;
//        height += 48;
        if(width == 1280) //23.6寸横屏
            height = 720;
        else if(width == 720) //23.6寸竖屏
            height = 1280;
        else if(width == 600) //7寸竖屏
            height = 1024;
        else if(width == 800) //10.1寸竖屏
            height = 1280;
        else if(width == 1366) //26寸横屏
            height = 768;
        else if(width == 768) //26寸竖屏
            height = 1366;
        else if(width == 1920) //50寸横屏
            height = 1080;
        else if(width == 1080) //50寸竖屏
            height = 1920;
        mLogger.e("screen density = " + context.getResources().getDisplayMetrics().density);
        mLogger.e("screen width = " + width + " height = " + height);

        if (!SDCardTools.isSDCardIsReady()) {
            return ERROR_NO_SDCARD;
        }

        mSharedPreferences = context.getSharedPreferences(AVM_DATA, Context.MODE_PRIVATE);

        //读取config.ini
        Properties avm = new Properties();
        File iniFileName = new File(path + "/" + DIRECTORY_CONFIG + "/" + FILE_CONFIG);
        FileInputStream fis;
        try {
            fis = new FileInputStream(iniFileName);
            avm.load(fis);
        } catch (FileNotFoundException e) {
            mLogger.e("config.ini not found");
            return ERROR_EMPTY_DATA;
        } catch (IOException e) {
            mLogger.e("Can not load config.ini file.");
            return ERROR_EMPTY_DATA;
        }

        if (!readConfigData(avm, CONFIG_COMMPORT, null)) {
            mLogger.e("未配置串口");
            return ERROR_EMPTY_DATA;
        }
        if (!readConfigData(avm, CONFIG_BAUDRATE, null)) {
            mLogger.e("未配置波特率");
            return ERROR_EMPTY_DATA;
        }
        readConfigData(avm, CONFIG_MONITOR_OPEN, "0");
        readConfigData(avm, CONFIG_SERVER_IP, "192.168.0.1");
        readConfigData(avm, CONFIG_SERVER_PORT, "8080");
        readConfigData(avm, CONFIG_PICK_IP, "192.168.0.1");
        readConfigData(avm, CONFIG_PICK_PORT, "8080");
        readConfigData(avm, CONFIG_VERSION, "14");
        readConfigData(avm, CONFIG_DEBUG, "1");
        readConfigData(avm, CONFIG_PROTECT_TIME, "5000");
        readConfigData(avm, CONFIG_REBOOT_TIME, "");

        String monitor = getConfigData(CONFIG_MONITOR_OPEN);
        if (monitor != null && monitor.equals("1")) {
            isMonitorOpen = true;
        } else {
            isMonitorOpen = false;
        }

        String debug = getConfigData(CONFIG_DEBUG);
        if (debug != null && debug.equals("1")) {
            isDebug = true;
        } else {
            isDebug = false;
        }

        readConfigData(avm, CONFIG_PAY_URL, "http://easytouch-pay.cn/wechat/page/pay.jsp");
        readConfigData(avm, CONFIG_PAY_ID, "0");
        readConfigData(avm, CONFIG_ALIPAY, "0");
        String alipay = getConfigData(CONFIG_ALIPAY);
        if (alipay != null && alipay.equals("1")) {
            alipayState = ALIPAY_VERSION_1;
        } else if(alipay != null && alipay.equals("2")) {
            alipayState = ALIPAY_VERSION_2;
        } else {
            alipayState = 0;
        }
        readConfigData(avm, CONFIG_ALIPAY_DISCOUNT, "10");
        readConfigData(avm, CONFIG_ALIPAY_PARTNER, "");
        readConfigData(avm, CONFIG_ALIPAY_NOTIFY_URL, "");
        readConfigData(avm, CONFIG_ALIPAY_KEY, "");

        readConfigData(avm, CONFIG_WECHAT, "0");
        String wechat = getConfigData(CONFIG_WECHAT);
        if (wechat != null && wechat.equals("1")) {
            wechatState = WECHAT_MODE_1;
        } else if(wechat != null && wechat.equals("2")) {
            wechatState = WECHAT_MODE_2;
        } else {
            wechatState = 0;
        }
        readConfigData(avm, CONFIG_WECHAT_DISCOUNT, "10");
        readConfigData(avm, CONFIG_WECHAT_ID, "");
        readConfigData(avm, CONFIG_WECHAT_KEY, "");
        readConfigData(avm, CONFIG_WECHAT_MAC_ID, "");
        readConfigData(avm, CONFIG_WECHAT_SUBMAC_ID, "");
        readConfigData(avm, CONFIG_WECHAT_NOTIFY_URL, "");

        readConfigData(avm, CONFIG_PAY_IP, "easytouch-pay.cn");
        readConfigData(avm, CONFIG_PAY_PORT, "6001");

        readConfigData(avm, CONFIG_CASH, "1");
        String cash = getConfigData(CONFIG_CASH);
        if (cash != null && cash.equals("1")) {
            isCash = true;
        }
        else
        {
            isCash = false;
        }
        readConfigData(avm, CONFIG_CARD, "0");
        String card = getConfigData(CONFIG_CARD);
        if (card != null && card.equals("1")) {
            isCard = true;
        }
        else
        {
            isCard = false;
        }
        readConfigData(avm, CONFIG_MOBILE, "1");
        String mobile = getConfigData(CONFIG_MOBILE);
        if (mobile != null && mobile.equals("1")) {
            isMobile = true;
        }
        else
        {
            isMobile = false;
        }
        readConfigData(avm, CONFIG_FACE, "0");
        String face = getConfigData(CONFIG_FACE);
        if (face != null && face.equals("1")) {
            isFace = true;
        }
        else
        {
            isFace = false;
        }

        try {
            fis.close();
        } catch (IOException e) {
            mLogger.e("file input stream close error" + e.getMessage());
        }

        return LOAD_DATA_SUCCESS;
    }

    public static int readMainConfig()
    {
        if(context == null || path == null || version == null)
        {
            return DATA_ERROR;
        }
        //读取main.ini
        Properties avm = new Properties();
        File iniFileName = new File(path + "/" + DIRECTORY_CONFIG + "/" + FILE_MAIN);
        FileInputStream fis;
        try {
            fis = new FileInputStream(iniFileName);
            avm.load(fis);
        } catch (FileNotFoundException e) {
            mLogger.e("main.ini not found");
            return ERROR_EMPTY_DATA;
        } catch (IOException e) {
            mLogger.e("Can not load main.ini file.");
            return ERROR_EMPTY_DATA;
        }

        readConfigData(avm, MAIN_DISPLAY_RATE, "0");
        readConfigData(avm, MAIN_IMAGE_TIME, "5");
        readConfigData(avm, MAIN_IMAGE_NAMES, "");
        readConfigData(avm, MAIN_VIDEO_NAMES, "");
        readConfigData(avm, MAIN_RECOMMEND, "");

        try {
            fis.close();
        } catch (IOException e) {
            mLogger.e("file input stream close error" + e.getMessage());
        }

        return LOAD_DATA_SUCCESS;
    }

    /**
     * 创建默认的config文件
     */
    public static boolean createDefaultMainConfig()
    {
        if(context == null || path == null || version == null)
        {
            return false;
        }
        Properties prop = new Properties();
        prop.setProperty(MAIN_DISPLAY_RATE, "0");
        readConfigData(prop, MAIN_DISPLAY_RATE, "0");
        prop.setProperty(MAIN_IMAGE_TIME, "5");
        readConfigData(prop, MAIN_IMAGE_TIME, "5");
        prop.setProperty(MAIN_IMAGE_NAMES, "");
        readConfigData(prop, MAIN_IMAGE_NAMES, "");
        prop.setProperty(MAIN_VIDEO_NAMES, "");
        readConfigData(prop, MAIN_VIDEO_NAMES, "");
        prop.setProperty(MAIN_RECOMMEND, "");
        readConfigData(prop, MAIN_RECOMMEND, "");

        FileOutputStream fos;
        try {
            File file = new File(path + "/" + DIRECTORY_CONFIG);
            if(!file.exists())
            {
                file.mkdirs();
            }
            File fileConfig = new File(file.getAbsolutePath() + "/" + FILE_MAIN);
            if(!fileConfig.exists())
            {
                fileConfig.createNewFile();
            }
            fos = new FileOutputStream(fileConfig);
            prop.store(fos, FILE_MAIN);
            fos.close();
        }
        catch (IOException e) {
            mLogger.e("Can not create file:" + e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 创建默认的config文件
     */
    public static boolean createDefaultConfig()
    {
        if(context == null || path == null || version == null)
        {
            return false;
        }
        Properties prop = new Properties();
        prop.setProperty(CONFIG_COMMPORT, "ttymxc1");
        readConfigData(prop, CONFIG_COMMPORT, "ttymxc1");
        prop.setProperty(CONFIG_BAUDRATE, "19200");
        readConfigData(prop, CONFIG_BAUDRATE, "19200");
        prop.setProperty(CONFIG_MONITOR_OPEN, "0");
        readConfigData(prop, CONFIG_MONITOR_OPEN, "0");
        isMonitorOpen = false;
        prop.setProperty(CONFIG_SERVER_IP, "192.168.0.1");
        readConfigData(prop, CONFIG_SERVER_IP, "192.168.0.1");
        prop.setProperty(CONFIG_SERVER_PORT, "8080");
        readConfigData(prop, CONFIG_SERVER_PORT, "8080");
        prop.setProperty(CONFIG_PICK_IP, "192.168.0.1");
        readConfigData(prop, CONFIG_PICK_IP, "192.168.0.1");
        prop.setProperty(CONFIG_PICK_PORT, "8080");
        readConfigData(prop, CONFIG_PICK_PORT, "8080");
        prop.setProperty(CONFIG_VERSION, "14");
        readConfigData(prop, CONFIG_VERSION, "14");
        prop.setProperty(CONFIG_DEBUG, "1");
        readConfigData(prop, CONFIG_DEBUG, "1");
        isDebug = true;
        prop.setProperty(CONFIG_PROTECT_TIME, "5000");
        readConfigData(prop, CONFIG_PROTECT_TIME, "5000");
        prop.setProperty(CONFIG_REBOOT_TIME, "");
        readConfigData(prop, CONFIG_REBOOT_TIME, "");
        prop.setProperty(CONFIG_PAY_URL, "http://easytouch-pay.cn/wechat/page/pay.jsp");
        readConfigData(prop, CONFIG_PAY_URL, "http://easytouch-pay.cn/wechat/page/pay.jsp");
        prop.setProperty(CONFIG_PAY_ID, "0");
        readConfigData(prop, CONFIG_PAY_ID, "0");
        prop.setProperty(CONFIG_ALIPAY, "0");
        readConfigData(prop, CONFIG_ALIPAY, "0");
        alipayState = 0;
        prop.setProperty(CONFIG_ALIPAY_DISCOUNT, "10");
        prop.setProperty(CONFIG_ALIPAY_PARTNER, "");
        prop.setProperty(CONFIG_ALIPAY_NOTIFY_URL, "");
        prop.setProperty(CONFIG_ALIPAY_KEY, "");
        readConfigData(prop, CONFIG_ALIPAY_DISCOUNT, "10");
        readConfigData(prop, CONFIG_ALIPAY_PARTNER, "");
        readConfigData(prop, CONFIG_ALIPAY_NOTIFY_URL, "");
        readConfigData(prop, CONFIG_ALIPAY_KEY, "");
        prop.setProperty(CONFIG_WECHAT, "0");
        readConfigData(prop, CONFIG_WECHAT, "0");
        wechatState = 0;
        prop.setProperty(CONFIG_WECHAT_DISCOUNT, "10");
        prop.setProperty(CONFIG_WECHAT_ID, "");
        prop.setProperty(CONFIG_WECHAT_KEY, "");
        prop.setProperty(CONFIG_WECHAT_MAC_ID, "");
        prop.setProperty(CONFIG_WECHAT_SUBMAC_ID, "");
        prop.setProperty(CONFIG_WECHAT_NOTIFY_URL, "");
        readConfigData(prop, CONFIG_WECHAT_DISCOUNT, "10");
        readConfigData(prop, CONFIG_WECHAT_ID, "");
        readConfigData(prop, CONFIG_WECHAT_KEY, "");
        readConfigData(prop, CONFIG_WECHAT_MAC_ID, "");
        readConfigData(prop, CONFIG_WECHAT_SUBMAC_ID, "");
        readConfigData(prop, CONFIG_WECHAT_NOTIFY_URL, "");
        prop.setProperty(CONFIG_PAY_IP, "easytouch-pay.cn");
        readConfigData(prop, CONFIG_PAY_IP, "easytouch-pay.cn");
        prop.setProperty(CONFIG_PAY_PORT, "6001");
        readConfigData(prop, CONFIG_PAY_PORT, "6001");

        prop.setProperty(CONFIG_CASH, "1");
        readConfigData(prop, CONFIG_CASH, "1");
        isCash = true;
        prop.setProperty(CONFIG_CARD, "0");
        readConfigData(prop, CONFIG_CARD, "0");
        isCard = false;
        prop.setProperty(CONFIG_MOBILE, "1");
        readConfigData(prop, CONFIG_MOBILE, "1");
        isMobile = true;
        prop.setProperty(CONFIG_FACE, "0");
        readConfigData(prop, CONFIG_FACE, "0");
        isFace = false;

        FileOutputStream fos;
        try {
            File file = new File(path + "/" + DIRECTORY_CONFIG);
            if(!file.exists())
            {
                file.mkdirs();
            }
            File fileConfig = new File(file.getAbsolutePath() + "/" + FILE_CONFIG);
            if(!fileConfig.exists())
            {
                fileConfig.createNewFile();
            }
            fos = new FileOutputStream(fileConfig);
            prop.store(fos, FILE_CONFIG);
            fos.close();
        }
        catch (IOException e) {
            mLogger.e("Can not create file:" + e.getMessage());
            return false;
        }
        return true;
    }

    public static boolean saveConfig()
    {
        if(context == null || path == null || version == null)
        {
            return false;
        }
        Properties prop = new Properties();
        prop.setProperty(CONFIG_COMMPORT, getConfigData(CONFIG_COMMPORT));
        prop.setProperty(CONFIG_BAUDRATE, getConfigData(CONFIG_BAUDRATE));
        prop.setProperty(CONFIG_MONITOR_OPEN, isMonitorOpen ? "1" : "0");
        prop.setProperty(CONFIG_SERVER_IP, getConfigData(CONFIG_SERVER_IP));
        prop.setProperty(CONFIG_SERVER_PORT, getConfigData(CONFIG_SERVER_PORT));
        prop.setProperty(CONFIG_PICK_IP, getConfigData(CONFIG_PICK_IP));
        prop.setProperty(CONFIG_PICK_PORT, getConfigData(CONFIG_PICK_PORT));
        prop.setProperty(CONFIG_VERSION, getConfigData(CONFIG_VERSION));
        prop.setProperty(CONFIG_DEBUG, isDebug ? "1" : "0");
        prop.setProperty(CONFIG_PROTECT_TIME, getConfigData(CONFIG_PROTECT_TIME));
        prop.setProperty(CONFIG_REBOOT_TIME, getConfigData(CONFIG_REBOOT_TIME));
        prop.setProperty(CONFIG_PAY_URL, getConfigData(CONFIG_PAY_URL));
        prop.setProperty(CONFIG_PAY_ID, getConfigData(CONFIG_PAY_ID));
        prop.setProperty(CONFIG_ALIPAY, getConfigData(CONFIG_ALIPAY));
        prop.setProperty(CONFIG_ALIPAY_DISCOUNT, getConfigData(CONFIG_ALIPAY_DISCOUNT));
        prop.setProperty(CONFIG_ALIPAY_PARTNER, getConfigData(CONFIG_ALIPAY_PARTNER));
        prop.setProperty(CONFIG_ALIPAY_NOTIFY_URL, getConfigData(CONFIG_ALIPAY_NOTIFY_URL));
        prop.setProperty(CONFIG_ALIPAY_KEY, getConfigData(CONFIG_ALIPAY_KEY));
        prop.setProperty(CONFIG_WECHAT, getConfigData(CONFIG_WECHAT));
        prop.setProperty(CONFIG_WECHAT_DISCOUNT, getConfigData(CONFIG_WECHAT_DISCOUNT));
        prop.setProperty(CONFIG_WECHAT_ID, getConfigData(CONFIG_WECHAT_ID));
        prop.setProperty(CONFIG_WECHAT_KEY, getConfigData(CONFIG_WECHAT_KEY));
        prop.setProperty(CONFIG_WECHAT_MAC_ID, getConfigData(CONFIG_WECHAT_MAC_ID));
        prop.setProperty(CONFIG_WECHAT_SUBMAC_ID, getConfigData(CONFIG_WECHAT_SUBMAC_ID));
        prop.setProperty(CONFIG_WECHAT_NOTIFY_URL, getConfigData(CONFIG_WECHAT_NOTIFY_URL));
        prop.setProperty(CONFIG_PAY_IP, getConfigData(CONFIG_PAY_IP));
        prop.setProperty(CONFIG_PAY_PORT, getConfigData(CONFIG_PAY_PORT));

        prop.setProperty(CONFIG_CASH, isCash ? "1" : "0");
        prop.setProperty(CONFIG_CARD, isCard ? "1" : "0");
        prop.setProperty(CONFIG_MOBILE, isMobile ? "1" : "0");
        prop.setProperty(CONFIG_FACE, isFace ? "1" : "0");

        FileOutputStream fos;
        try {
            File file = new File(path + "/" + DIRECTORY_CONFIG);
            if(!file.exists())
            {
                file.mkdirs();
            }
            File fileConfig = new File(file.getAbsolutePath() + "/" + FILE_CONFIG);
            if(!fileConfig.exists())
            {
                fileConfig.createNewFile();
            }
            fos = new FileOutputStream(fileConfig);
            prop.store(fos, FILE_CONFIG);
            fos.close();
        }
        catch (IOException e) {
            mLogger.e("Can not create file:" + e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 读取游戏配置
     * @return 读取结果
     */
    public static int loadGameConfig() {
        if(context == null || path == null || version == null)
        {
            return DATA_ERROR;
        }
        if (!SDCardTools.isSDCardIsReady()) {
            return ERROR_NO_SDCARD;
        }

        //读取game.ini
        Properties gameProperties = new Properties();
        File gameIniFileName = new File(path + "/" + DIRECTORY_CONFIG + "/" + FILE_GAME);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(gameIniFileName);
            gameProperties.load(fis);
        } catch (FileNotFoundException e) {
            mLogger.e("game.ini not found");
            return ERROR_EMPTY_DATA;
        } catch (IOException e) {
            mLogger.e("Can not load game.ini file.");
            return ERROR_EMPTY_DATA;
        }
        readConfigData(gameProperties, GAME_ENABLE, "0");
        readConfigData(gameProperties, GAME_PACKAGE, ""); //com.game.turn_table_simple
        readConfigData(gameProperties, GAME_ACTIVITY, ""); //com.game.turn_table_simple.TurnTableActivity
        readConfigData(gameProperties, GAME_GIFT, ""); //01_0.1;02_0.2;03_0.3;04_0.4
        readConfigData(gameProperties, GAME_CODE, ""); //01;02

        String game = getConfigData(GAME_ENABLE);
        if (game != null && game.equals("1")) {
            isGameEnable = true;
        } else {
            isGameEnable = false;
        }

        try {
            fis.close();
        } catch (IOException e) {
            mLogger.e("file input stream close error" + e.getMessage());
        }

        return LOAD_DATA_SUCCESS;
    }

    /**
     * 创建默认的游戏配置文件
     */
    public static boolean createDefaultGameConfig()
    {
        if(context == null || path == null || version == null)
        {
            return false;
        }
        Properties prop = new Properties();
        prop.setProperty(GAME_ENABLE, "0");
        readConfigData(prop, GAME_ENABLE, "0");
        isGameEnable = false;
        prop.setProperty(GAME_PACKAGE, "");
        readConfigData(prop, GAME_PACKAGE, "");
        prop.setProperty(GAME_ACTIVITY, "");
        readConfigData(prop, GAME_ACTIVITY, "");
        prop.setProperty(GAME_GIFT, "");
        readConfigData(prop, GAME_GIFT, "");
        prop.setProperty(GAME_CODE, "");
        readConfigData(prop, GAME_CODE, "");
        FileOutputStream fos;
        try {
            File file = new File(path + "/" + DIRECTORY_CONFIG);
            if(!file.exists())
            {
                file.mkdirs();
            }
            File fileConfig = new File(file.getAbsolutePath() + "/" + FILE_GAME);
            if(!fileConfig.exists())
            {
                fileConfig.createNewFile();
            }
            fos = new FileOutputStream(fileConfig);
            prop.store(fos, FILE_GAME);
            fos.close();
        }
        catch (IOException e) {
            mLogger.e("Can not create file:" + e.getMessage());
            return false;
        }
        return true;
    }

    public static int readNbposConfig()
    {
        if(context == null || path == null || version == null)
        {
            return DATA_ERROR;
        }
        //读取nbpos.ini
        Properties avm = new Properties();
        File iniFileName = new File(path + "/" + DIRECTORY_CONFIG + "/" + FILE_NBPOS);
        FileInputStream fis;
        try {
            fis = new FileInputStream(iniFileName);
            avm.load(fis);
        } catch (FileNotFoundException e) {
            mLogger.e("nbpos.ini not found");
            return ERROR_EMPTY_DATA;
        } catch (IOException e) {
            mLogger.e("Can not load nbpos.ini file.");
            return ERROR_EMPTY_DATA;
        }

        readConfigData(avm, NBPOS_STATE, "0");
        readConfigData(avm, NBPOS_DISCOUNT, "10");
        readConfigData(avm, NBPOS_IP, "192.168.0.1");
        readConfigData(avm, NBPOS_PORT, "0");
        readConfigData(avm, NBPOS_TERM_INFO, "");
        readConfigData(avm, NBPOS_SSL_SN, "");
        readConfigData(avm, NBPOS_MCHT_ID, "");
        readConfigData(avm, NBPOS_TERM_ID, "");
        readConfigData(avm, NBPOS_AUTH_SN, "");
        readConfigData(avm, NBPOS_BAUD_RATE, "19200");
        readConfigData(avm, NBPOS_COMM_PORT, "");
        readConfigData(avm, NBPOS_OPER_ID, "");
        readConfigData(avm, NBPOS_POS_ID, "0");

        try {
            fis.close();
        } catch (IOException e) {
            mLogger.e("file input stream close error" + e.getMessage());
        }

        return LOAD_DATA_SUCCESS;
    }

    /**
     * 创建默认的nbpos文件
     */
    public static boolean createDefaultNbposConfig()
    {
        if(context == null || path == null || version == null)
        {
            return false;
        }
        Properties prop = new Properties();

        prop.setProperty(NBPOS_STATE, "0");
        readConfigData(prop, NBPOS_STATE, "0");
        prop.setProperty(NBPOS_DISCOUNT, "10");
        readConfigData(prop, NBPOS_DISCOUNT, "10");
        prop.setProperty(NBPOS_IP, "192.168.0.1");
        readConfigData(prop, NBPOS_IP, "192.168.0.1");
        prop.setProperty(NBPOS_PORT, "0");
        readConfigData(prop, NBPOS_PORT, "0");
        prop.setProperty(NBPOS_TERM_INFO, "");
        readConfigData(prop, NBPOS_TERM_INFO, "");
        prop.setProperty(NBPOS_SSL_SN, "");
        readConfigData(prop, NBPOS_SSL_SN, "");
        prop.setProperty(NBPOS_MCHT_ID, "");
        readConfigData(prop, NBPOS_MCHT_ID, "");
        prop.setProperty(NBPOS_TERM_ID, "");
        readConfigData(prop, NBPOS_TERM_ID, "");
        prop.setProperty(NBPOS_AUTH_SN, "");
        readConfigData(prop, NBPOS_AUTH_SN, "");
        prop.setProperty(NBPOS_BAUD_RATE, "19200");
        readConfigData(prop, NBPOS_BAUD_RATE, "19200");
        prop.setProperty(NBPOS_COMM_PORT, "");
        readConfigData(prop, NBPOS_COMM_PORT, "");
        prop.setProperty(NBPOS_OPER_ID, "");
        readConfigData(prop, NBPOS_OPER_ID, "");
        prop.setProperty(NBPOS_POS_ID, "0");
        readConfigData(prop, NBPOS_POS_ID, "0");

        FileOutputStream fos;
        try {
            File file = new File(path + "/" + DIRECTORY_CONFIG);
            if(!file.exists())
            {
                file.mkdirs();
            }
            File fileConfig = new File(file.getAbsolutePath() + "/" + FILE_NBPOS);
            if(!fileConfig.exists())
            {
                fileConfig.createNewFile();
            }
            fos = new FileOutputStream(fileConfig);
            prop.store(fos, FILE_NBPOS);
            fos.close();
        }
        catch (IOException e) {
            mLogger.e("Can not create file:" + e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 读取配置项
     * @param pIni 属性对象
     * @param pKey 要读取的项
     * @param pDefaultValue 默认值
     * @return 是否成功
     */
    private static boolean readConfigData(final Properties pIni, final String pKey, final String pDefaultValue) {
        String value = pIni.getProperty(pKey);
        if (value == null || "".equals(value)) {
            if (pDefaultValue != null)
                mConfigMap.put(pKey, pDefaultValue);
            return false;
        } else {
            mLogger.e(pKey + " = " + value);
            mConfigMap.put(pKey, value);
        }
        return true;
    }

    /**
     * 获取配置项
     * @param pKey 要获取的项
     * @return 值
     */
    public static String getConfigData(final String pKey) {
        return mConfigMap.get(pKey);
    }

    /**
     * 读取自定义配置
     * @param pConfigFile 配置文件名
     * @param pKey 配置项
     * @return 值
     */
    public static String getCustomConfigData(final String pConfigFile, final String pKey)
    {
        String result = "";
        //读取nbpos.ini
        Properties avm = new Properties();
        File iniFileName = new File(path + "/" + DIRECTORY_CONFIG + "/" + pConfigFile);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(iniFileName);
            avm.load(fis);
            String value = avm.getProperty(pKey);
            if (value == null || "".equals(value)) {
                return result;
            }
            else {
                return value;
            }
        } catch (FileNotFoundException e) {
            mLogger.e("file: " + pConfigFile + " not found");
            return result;
        } catch (IOException e) {
            mLogger.e("Can not load " + pConfigFile + " file.");
            return result;
        } finally {
            try {
                if(fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 读取商品配置
     */
    public static void loadGoodsXML() {
        if(context == null || path == null || version == null)
        {
            return;
        }
        if(goodsList != null)
        {
            goodsList.clear();
        }
        //实例化一个文档构建器工厂
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            //通过文档构建器工厂获取一个文档构建器
            DocumentBuilder db = dbf.newDocumentBuilder();
            //通过文档通过文档构建器构建一个文档实例
            Document doc = db.parse("file://" + path + "/" + DIRECTORY_CONFIG + "/" + FILE_GOODS);
            NodeList nl1 = doc.getElementsByTagName("goods");
            if (nl1.getLength() == 0) {
                return;
            }
            Node n1 = nl1.item(0);
            NodeList nl2 = n1.getChildNodes();
            if (nl2.getLength() == 0) {
                return;
            }
            for (int i = 0; i < nl2.getLength(); i++) {
                Node n = nl2.item(i);
                if (!n.getNodeName().equals("item") || n.getNodeType() != Node.ELEMENT_NODE) {
                    continue;
                }
                NamedNodeMap map = n.getAttributes();
                Node NAME = map.getNamedItem("name");
                String name = NAME.getNodeValue();
                Node CODE = map.getNamedItem("code"); //十进制
                String code = CODE.getNodeValue();
                Node IMAGE = map.getNamedItem("image");
                String image = IMAGE.getNodeValue();
                Node TYPE = map.getNamedItem("type");
                String type = TYPE.getNodeValue();
                Node BC = map.getNamedItem("bc");
                String bc = BC.getNodeValue();

                GoodsModel goods = new GoodsModel();
                goods.setName(name);
                goods.setCode(code != null ? code : "");
                goods.setImage(image);
                goods.setType(type);
                goods.setBarCode(bc != null ? bc : "");

                goodsList.add(goods);
                mLogger.i("goods code:" + goods.getCode() + " name:" + goods.getName());
            }
        } catch (FileNotFoundException e) {
            mLogger.e("goods.xml not found");
        } catch (ParserConfigurationException ex) {
            mLogger.e("goods.xml ParserConfigurationException:" + ex.getMessage());
        } catch (IOException ex) {
            mLogger.e("goods.xml IOException:" + ex.getMessage());
        } catch (SAXException ex) {
            mLogger.e("goods.xml SAXException:" + ex.getMessage());
        }
        mLogger.i("goods count:" + goodsList.size());
//        for (GoodsModel goods: goodsList) {
//            mLogger.i(goods.toString());
//        }
    }

    /**
     * 获得串口对象
     *
     * @param portName 串口设备名称
     * @param baudrate 波特率
     * @return 串口对象
     * @throws SecurityException
     * @throws IOException
     * @throws InvalidParameterException
     */
    public static SerialPort createSerialPort(final String portName, final String baudrate) throws SecurityException, IOException, InvalidParameterException {
        SerialPort serialport;
        try {
            serialport = new SerialPort(new File("/dev/" + portName), Integer.parseInt(baudrate), 0); //ttyUSB0 dev/ttymxc2 dev/ttymxc0
        } catch (NumberFormatException e)
        {
            serialport = new SerialPort(new File("/dev/ttymxc1"), 19200, 0);
        }
        return serialport;
    }

    /**
     * 关闭串口
     */
    public static void closeSerialPort(SerialPort pSerialPort) {
        if (pSerialPort != null) {
            pSerialPort.close();
            pSerialPort = null;
        }
    }

    public static String getMacNo() {
        if ("00000000".equals(mMacNo)) {
            if(mSharedPreferences == null)
            {
                return "00000000";
            }
            String no = mSharedPreferences.getString(AVM_NO, "");
            if (!"".equals(no))
                mMacNo = no;
        }
        return mMacNo;
    }

    public static void setMacNo(final String mac) {
        if (mac != null && !mac.equals("00000000") && mac.length() == 8 && mSharedPreferences != null) {
            mSharedPreferences.edit().putString(AVM_NO, mac).commit();
            mMacNo = mac;
        }
    }

    public static String getAvmVersion() {
        return mAvmVersion;
    }

    public static void setAvmVersion(final String pAvmVersion) {
        mAvmVersion = pAvmVersion;
    }

    public static String getMacType() {
        return mMacType;
    }

    public static void setMacType(String pMacType) {
        mMacType = pMacType;
    }

    public static String getDrinkNum() {
        return mDrinkNum;
    }

    public static void setDrinkNum(String pDrinkNum) {
        mDrinkNum = pDrinkNum;
    }

    public static String getFoodsNum() {
        return mFoodsNum;
    }

    public static void setFoodsNum(String pFoodsNum) {
        mFoodsNum = pFoodsNum;
    }

    public static String getNoodleNum() {
        return mNoodleNum;
    }

    public static void setNoodleNum(String pNoodleNum) {
        mNoodleNum = pNoodleNum;
    }

    public static String getDrinkColumnNum() {
        return mDrinkColumnNum;
    }

    public static void setDrinkColumnNum(String pDrinkColumnNum) {
        mDrinkColumnNum = pDrinkColumnNum;
    }

    public static String getFoodsColumnNum() {
        return mFoodsColumnNum;
    }

    public static void setFoodsColumnNum(String pFoodsColumnNum) {
        mFoodsColumnNum = pFoodsColumnNum;
    }

    public static String getNoodleColumnNum() {
        return mNoodleColumnNum;
    }

    public static void setNoodleColumnNum(String pNoodleColumnNum) {
        mNoodleColumnNum = pNoodleColumnNum;
    }

    /**
     * 获取主控的唯一ID号
     * @return 主控唯一ID号
     */
    public static String getUUID()
    {
        return mUUID;
    }

    public static void setUUID(final String uuid)
    {
        mUUID = uuid;
    }

    /**
     * 获取支付宝折扣率
     * @return 折扣率
     */
    public static double getAlipayDiscount()
    {
        return getDiscount(CONFIG_ALIPAY_DISCOUNT);
    }

    /**
     * 获取微信折扣率
     * @return 折扣率
     */
    public static double getWechatDiscount()
    {
        return getDiscount(CONFIG_WECHAT_DISCOUNT);
    }

    /**
     * 获取宁波pos折扣率
     * @return 折扣率
     */
    public static double getNbposDiscount() { return getDiscount(NBPOS_DISCOUNT); }

    /**
     * 获取折扣率
     * @param pKey 要获取的支付方式
     * @return 折扣率
     */
    private static double getDiscount(final String pKey)
    {
        String discountStr = getConfigData(pKey);
        double discount = 10.0;
        try
        {
            discount = Double.parseDouble(discountStr);
        }
        catch (NumberFormatException e)
        {}
        if(discount > 10)
            discount = 10.0;
        if(discount < 0)
            discount = 10.0;
        return discount;
    }

    /**
     * 转换货道号
     * @param box 货柜号
     * @param road 货道号
     * @return
     */
    public static String convertColumn(int box, int road)
    {
        String foodsRoadNumStr = getFoodsColumnNum();
        if(foodsRoadNumStr == null || "".equals(foodsRoadNumStr))
        {
            return "0000";
        }
        int foodsRoadNum = 48;
        try {
            foodsRoadNum = Integer.parseInt(foodsRoadNumStr);
        }
        catch (NumberFormatException e)
        {}
        int row = 8; //一行多少个商品
        if((foodsRoadNum % 8) != 0) //60和70的是一行10个商品
        {
            row = 10;
        }
        String result = "";
        String roadStr = "";
        if(box >= 6 && box <= 9) //食品机
        {
            int boxMinus = 9 - box;
            int boxPos = boxMinus * 48 + road;
            if(boxPos <= foodsRoadNum)
            {
                result = "09";
            }
            else
            {
                result = "08";
                boxPos -= foodsRoadNum;
            }
            if(row == 8)
            {
                int i = boxPos  / 8;
                int j = boxPos % 8;
                if( j != 0)
                    i++;
                else
                    j = 8;
                roadStr += i + "" + j;
            }
            else
            {
                roadStr += boxPos - 1 + 10;
            }
            result += roadStr;
        }
        else //饮料机或商品柜
        {
            result = Tools.addLeftZero(String.valueOf(box), 2) + Tools.addLeftZero(String.valueOf(road), 2);
        }
        return result;
    }

    /**
     * 反向转换货道号为售货机出货编号
     * @param pCode 2位或3位编号
     * @return 售货机出货编号，2位货柜号+2位货道号，十进制，参数错误返回null
     */
    public static String convertColumn(final String pCode)
    {
        int box = 9;
        int column = 1;
        int s; //十位
        int g; //个位
        if(pCode == null || (pCode.length() != 2 && pCode.length() != 3))
        {
            return null;
        }
        if(pCode.length() == 2)
        {
            box = 9;
            try {
                column = Integer.parseInt(pCode);
                s = Integer.parseInt(pCode.substring(0, 1));
                g = Integer.parseInt(pCode.substring(1));
            }
            catch (NumberFormatException e)
            {
                return null;
            }
        }
        else
        {
            try
            {
                box = Integer.parseInt(pCode.substring(0, 1));
                column = Integer.parseInt(pCode.substring(1));
                s = Integer.parseInt(pCode.substring(1, 2));
                g = Integer.parseInt(pCode.substring(2));
            }
            catch (NumberFormatException e)
            {
                return null;
            }
        }
        if(box >= 1 && box <= 5) //商品柜
        {
            return Tools.addLeftZero(String.valueOf(box), 2) + Tools.addLeftZero(String.valueOf(column), 2);
        }
        //食品机，情况比较复杂
        String foodsRoadNumStr = getFoodsColumnNum();
        if(foodsRoadNumStr == null || "".equals(foodsRoadNumStr))
        {
            return null;
        }
        int foodsRoadNum = 48;
        try {
            foodsRoadNum = Integer.parseInt(foodsRoadNumStr);
        }
        catch (NumberFormatException e)
        {}
        int row = 8; //一行多少个商品
        if((foodsRoadNum % 8) != 0) //60和70的是一行10个商品
        {
            row = 10;
        }
        String foodsNumStr = getFoodsNum();
        if(foodsNumStr == null || "".equals(foodsNumStr))
        {
            return null;
        }
        int foodsNum = 1;
        try {
            foodsNum = Integer.parseInt(foodsNumStr);
        }
        catch (NumberFormatException e)
        {}
        int minus = 9 - box;
        int col;
        if(row == 8)
        {
            col = (s - 1) * 8 + g;
        }
        else
        {
            col = (s - 1) * 10 + g + 1;
        }
        col = minus * foodsRoadNum + col;
        int i = col / 48;
        int j = col % 48;
        if( j == 0) {
            i--;
            j = 48;
        }
        box = 9 - i;
        column = j;
        return Tools.addLeftZero(String.valueOf(box), 2) + Tools.addLeftZero(String.valueOf(column), 2);
    }

    /**
     * 设置货柜料道数量
     * @param box 货柜编号
     * @param num 数量
     */
    public static void setColumnNum(final int box, final int num)
    {
        if(mColumnNumMap == null)
        {
            mColumnNumMap = new HashMap<Integer, Integer>();
        }
        mColumnNumMap.put(box, num);
    }

    /**
     * 获取货柜料道数量
     * @param box 货柜编号
     * @return 货道数量
     */
    public static int getColumnNum(final int box)
    {
        if(mColumnNumMap != null && mColumnNumMap.containsKey(box))
        {
            return mColumnNumMap.get(box);
        }
        else
        {
            return 0;
        }
    }
}
